package system.train;

import system.communication.Monitor;
import system.track.Block;
import system.track.Direction;
import system.ui.Engine;
/**
 * This class is an implementation of the Train interface
 * and is subject to modifications.
 *
 * This has been modified in Cycle two to use the reservations system
 * and to stop until a reservation is available.
 * 
 * @author Yasmine  
 */

public class Train extends Thread
{
   private Block currentBlock;
   private Route currentRoute;
   protected boolean waiting;
   private boolean running;
   private int speed;
   private Direction currentDirection;
   private int id;
   
   public Train(Block block, int id)
   {
       currentBlock = block;
       waiting = false;
       running = true;
       speed = 0;
       this.id = id;
   }

   public int getID()
   {
       return id;
   }
   
   public synchronized void setRoute(Direction direction)
   {
       currentRoute = Route.createRoute(direction);
   }

    protected boolean isRunning()
    {
        return running;
    }
   
   public synchronized void setDirection(Direction direction)
   {
       currentDirection = direction;
       Engine.getInstance().postTrainDirection(id, direction);
   }
   
   public Direction getDirection()
   {
       return currentDirection;
   }
    
   public Block getCurrentBlock()
   {
       return currentBlock; 
   }
   
   public synchronized void setCurrentBlock(Block block)
   {
       currentBlock = block;
       Engine.getInstance().postTrainReservations(id, getReservedBlocks());
   }

   public int[] getReservedBlocks()
   {
       return new int[] {currentBlock.getID()};
   }

   public int getSpeed()
   {
       return speed;
   }
   
   public synchronized void setSpeed(int speed)
   {
       if(speed > 0 || speed < 7)
       {
            this.speed = speed;
       }
   }
   
   public synchronized void kill()
   {
       running = false;
       pause();
       tripSensor();
   }

   public synchronized void pause()
   {
       RouteActions.STOP.executeAction(this);
   }

   public synchronized void tripSensor()
   {
       this.waiting = false;
       try
       {
            Thread.sleep(2000);
       }
       catch(InterruptedException e)
       {
           System.out.println(e.getMessage());
           e.printStackTrace();
       }
       notify();
   }
    
   protected synchronized void waitForSensor()
   {
       try
       {
           while(waiting)
           {
               wait();
           }
       }
       catch(InterruptedException e)
       {
           System.out.println("TRAIN THREAD WAS INTERRUPTED!  WTF??");
           e.printStackTrace();
       }
   }

   
   @Override
   public void run()
   {
       while(running)
       {
           while(!waiting && running)
           {
               waiting = currentRoute.executeNextAction(this);
           }
           waitForSensor();
       }
   }

   public boolean isHandControlled()
   {
       return false;
   }
}
